package com.appium.manager.config;


import io.appium.java_client.remote.AutomationName;
import io.appium.java_client.remote.MobileCapabilityType;
import io.appium.java_client.remote.MobilePlatform;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 负责读取appiumConfig.properties配置文件
 * @author 大忽悠
 * @create 2022/7/7 10:19
 */
@Slf4j
public class AppiumConfig {
    /**
     * 配置文件默认的路径
     */
    public static final String DEFAULT_CONFIG_FILE_PATH="appiumConfig.properties";

    /**
     * 配置中心
     */
    private static final Map<String,String> DEFAULT_CONFIGS=new HashMap<>();

    private static final Properties PRO=new Properties();


    /**
     * 配置文件路径
     */
    private String configFilePath=DEFAULT_CONFIG_FILE_PATH;


    //-------------------------------常用配置类属性常量-----------------------------------------

    /**
     * 设备名,默认为: 127.0.0.1:62001 (夜神模拟器)
     */
    public static final String DEVICE_NAME="deviceName";

    /**
     * 平台名,默认为: Android
     */
    public static final String PLATFORM_NAME="platformName";

    /**
     * 包名---默认为io.ionic.starter
     */
    public static final String APP_PACKAGE="appPackage";

    /**
     * 活动名---页面名---默认为.MainActivity---即启动页
     */
    public static final String APP_ACTIVITY="appActivity";

    /**
     * 使用的引擎,默认为: uiautomator2
     */
    public static final String AUTOMATION_NAME="automationName";

    /**
     * 每次测试前是否要清空app,默认为false,表示每次启动应用前,都先清空应用数据
     */
    public static final String NO_RESET="noReset";

    /**
     * appium服务其通信地址,默认为: "http://127.0.0.1:4723/wd/hub"
     */
    public static final String APPIUM_SERVER_ADDRESS="appiumServerAddress";

    /**
     * 隐式等待时间--默认为30s---在这30s内会不间断的查找对应的元素在页面上是否存在
     */
    public  static final String IMPLICITLY_WAIT="implicitlyWait";

    /**
     * webview,默认为WEBVIEW_io.ionic.starter
     */
    public static final String WEBVIEW_CONTEXT="webview";

    /**
     * 启动应用程序前,先卸载应用程序,然后重新安装
     */
    public static final String CLEAR_SYSTEM_FILES= MobileCapabilityType.CLEAR_SYSTEM_FILES;



    //------------------------IOS环境额外参数---------------------------------

    public static final String DEVICE_TYPE="deviceType";

    public static final String IOS="ios";

    public static final String ANDROID ="android";

    /**
     *  参数含义参考: app=/Users/lizeng/VSCodeWorkspace/aipsi-cws-app/android/app/build/outputs/apk/debug/app-debug.apk
     *  默认值为: app-debug.apk--即在当前项目路径下
     */
    public static final String APP="app";

    /**
     * 是否开启ios测试环境
     */
    private static Boolean ios=false;

    /**
     * 苹果设备的UDID号
     */
    public static final String UDID="UDID";

    //---------------------异常快照-------------------------

    public static final String OPEN_EX_SNAPSHOT="openExSnapshot";

    public static final String SNAPSHOT_FILE_PATH="snapshotFilePath";

    /**
     * 是否在启动前删除上次生成的异常快照和截图,默认为true
     */
    public static final String REMOVE_BEFORE_START="removeBeforeStart";

    /**
     * 默认属性配置
     */
    static {
        DEFAULT_CONFIGS.put(DEVICE_NAME,"127.0.0.1:62001");
        DEFAULT_CONFIGS.put(PLATFORM_NAME,"Android");
        DEFAULT_CONFIGS.put(APP_PACKAGE,"io.ionic.starter");
        DEFAULT_CONFIGS.put(APP_ACTIVITY,".MainActivity");
        DEFAULT_CONFIGS.put(AUTOMATION_NAME,"uiautomator2");
        DEFAULT_CONFIGS.put(NO_RESET,"false");
        DEFAULT_CONFIGS.put(APPIUM_SERVER_ADDRESS,"http://127.0.0.1:4723/wd/hub");
        DEFAULT_CONFIGS.put(IMPLICITLY_WAIT,"30");
        DEFAULT_CONFIGS.put(WEBVIEW_CONTEXT,"WEBVIEW_io.ionic.starter");
        DEFAULT_CONFIGS.put(APP,"app-debug.apk");
        DEFAULT_CONFIGS.put(OPEN_EX_SNAPSHOT,"false");
        DEFAULT_CONFIGS.put(SNAPSHOT_FILE_PATH,"snapshot/");
        DEFAULT_CONFIGS.put(REMOVE_BEFORE_START,"true");
        DEFAULT_CONFIGS.put(CLEAR_SYSTEM_FILES,"false");

        //判断是否选择了IOS
        //1.设置了VM环境变量,自动开启
        String deviceType = System.getProperty(DEVICE_TYPE);
        if((deviceType!=null && deviceType.equals(IOS))){
            changeToIOS();
        }
    }

    private static void changeToIOS() {
        ios=true;
        DEFAULT_CONFIGS.put(PLATFORM_NAME, MobilePlatform.IOS);
        DEFAULT_CONFIGS.put(AUTOMATION_NAME, AutomationName.IOS_XCUI_TEST);
        log.info("开启了ios测试环境");
    }


    public AppiumConfig(String configFilePath) {
        this.configFilePath = configFilePath;
        init();
    }

    public AppiumConfig() {
        init();
    }

    /**
     * 读取相关配置信息
     * 默认查询classPath路径,如果类路径下不存在,再去查询文件系统路径
     */
    private void init() {
        try {
            InputStream resourceAsStream = AppiumConfig.class.getClassLoader().getResourceAsStream(configFilePath);
            PRO.load(resourceAsStream);
            //2.如果配置环境中设置了ios=true,也会开启IOS环境
            if("true".equals(PRO.get(IOS))){
                changeToIOS();
            }else if(!ios){
                    log.info("开启了android环境测试");
            }
        } catch (IOException | NullPointerException e) {
           log.info("classPath下没有找到对应的配置文件");
            try {
                FileInputStream inputStream = new FileInputStream(configFilePath);
                PRO.load(inputStream);
            } catch (IOException ex) {
                log.info("classpath和文件系统中均为发现存在名为"+configFilePath+"的配置文件,将统一使用默认配置");
            }
        }
    }

    /**
     * 获取相关属性
     */
    public String getParam(String key){
        String val = (String) PRO.get(key);
        return val!=null?val:DEFAULT_CONFIGS.get(key);
    }

    /**
     * 是否开启了IOS测试环境
     */
    public Boolean openIOS(){
       return ios;
    }
}
